package com.xiaoxiao.spatialite;

import android.content.Context;

import org.oscim.layers.tile.buildings.BuildingLayer;
import org.oscim.map.Viewport;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.source.mapfile.MapFileTileSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spatialite.database.SQLiteDatabase;

import java.io.File;
import java.io.RandomAccessFile;

public class SpatialiteTileSource extends MapFileTileSource {

    private static final Logger log = LoggerFactory.getLogger(MapFileTileSource.class);
    private Context mContext; // 上下文，读取Spatialite所需参数
    private SpatialiteDbHelper spatialiteDbHelper;
    private SQLiteDatabase spatialiteDatabase;

    /**
     * Amount of cache blocks that the index cache should store.
     */
    private static final int INDEX_CACHE_SIZE = 64;
    private static final String READ_ONLY_MODE = "r";

    IndexCache databaseIndexCache;
    boolean experimental;
    File mapFile;
    private RandomAccessFile mInputFile;

    public SpatialiteTileSource(Context mContext) {
        this(mContext, Viewport.MIN_ZOOM_LEVEL, Viewport.MAX_ZOOM_LEVEL);
    }

    public SpatialiteTileSource(Context mContext, int zoomMin, int zoomMax) {
        this(mContext, zoomMin, zoomMax, BuildingLayer.MIN_ZOOM);
    }

    public SpatialiteTileSource(Context mContext, int zoomMin, int zoomMax, int overZoom) {
        super(zoomMin, zoomMax, overZoom);
        this.mContext = mContext;
    }

    public boolean setMapFile(String filename) {
        setOption("file", filename);

        File file = new File(filename);

        if (!file.exists()) {
            return false;
        } else if (!file.isFile()) {
            return false;
        } else if (!file.canRead()) {
            return false;
        }

        return true;
    }

    @Override
    public ITileDataSource getDataSource() {
        try {
            return new SpatialiteTileDataSource(this, spatialiteDatabase);
        } catch (Exception e) {
            log.debug(e.getMessage());
        }
        return null;
    }

    @Override
    public OpenResult open() {
        if (!options.containsKey("file"))
            return new OpenResult("no map file set");

        try {
            // make sure to close any previously opened file first
            //close();

            File file = new File(options.get("file"));

            // 检查文件是否存在是否可读
            if (!file.exists()) {
                return new OpenResult("file does not exist: " + file);
            } else if (!file.isFile()) {
                return new OpenResult("not a file: " + file);
            } else if (!file.canRead()) {
                return new OpenResult("cannot read file: " + file);
            }

            // 打开Spatialite文件
            spatialiteDbHelper=new SpatialiteDbHelper(this.mContext, file.getAbsolutePath(), null, 1);
            spatialiteDatabase=spatialiteDbHelper.getReadableDatabase();
            OpenResult openResult = new OpenResult();
//            if (spatialiteDatabase.isOpen()){
//                openResult = new OpenResult("spatialite database cant open"+spatialiteDatabase.getPath());
//            }

            if (!openResult.isSuccess()) {
                close();
                return openResult;
            }
            mapFile = file;
            databaseIndexCache = new IndexCache(mInputFile, INDEX_CACHE_SIZE);

            // Experimental?
            //experimental = fileInfo.fileVersion == 4;

            // log.debug("File version: " + fileInfo.fileVersion);
            return OpenResult.SUCCESS;
        } catch (Exception e) {
            log.error(e.getMessage());
            // make sure that the file is closed
            close();
            return new OpenResult(e.getMessage());
        }
    }

    @Override
    public void close() {
        if (spatialiteDatabase!=null&&spatialiteDatabase.isOpen()){
            spatialiteDatabase.close();
        }
    }
}
